package server

import (
	"gitee.com/hxchjm/go-admin/internal/models"
	"gitee.com/hxchjm/go-admin/internal/service"
	"gitee.com/hxchjm/go-admin/pkg/ecode"
	"gitee.com/hxchjm/go-admin/pkg/jwtauth"
	"gitee.com/hxchjm/go-admin/pkg/permit"
	"github.com/gin-gonic/gin"
	"net/http"
)

type server struct {
	svr *gin.Engine
}

func New() *server {
	s := &server{
		svr: gin.Default(),
	}
	s.svr.Use(Logger)
	s.route()
	return s
}

func (s *server) route() {
	g := s.svr.Group("/api/v1")
	{
		g.POST("/login", func(c *gin.Context) {
			req := &models.ReqLogin{}
			if err := c.Bind(req); err != nil {
				return
			}
			resp, err := service.Login(c, req)
			s.JSON(c, resp, err)
		})

		g.GET("/captcha", func(c *gin.Context) {
			resp, err := service.GenCaptcha(c)
			s.JSON(c, resp, err)
		})
	}

	g0 := s.svr.Group("/api/v1").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		g0.POST("/logout", func(c *gin.Context) {
			resp, err := service.Logout(c)
			s.JSON(c, resp, err)
		})
		g0.GET("/getinfo", func(c *gin.Context) {
			resp, err := service.GetInfo(c)
			s.JSON(c, resp, err)
		})
		g0.GET("/menurole", func(c *gin.Context) {
			resp, err := service.GetRoleMenu(c)
			s.JSON(c, resp, err)
		})
		g0.GET("/deptTree", func(c *gin.Context) {
			req := &models.ReqDeptGetPage{}
			if err := c.Bind(req); err != nil {
				return
			}
			resp, err := service.Dept{}.Get2Tree(c, req)
			s.JSON(c, resp, err)
		})
		g0.GET("/roleMenuTreeselect/:roleId", func(c *gin.Context) {
			req := &models.ReqSelectRole{}
			if err := c.BindUri(req); err != nil {
				return
			}
			resp, err := service.Menu{}.GetMenuTreeSelect(c, req)
			s.JSON(c, resp, err)
		})
		g0.GET("/roleDeptTreeselect/:roleId", func(c *gin.Context) {
			req := &models.ReqGetDeptTreeRoleSelect{}
			if err := c.BindUri(req); err != nil {
				return
			}
			resp, err := service.Dept{}.GetDeptTreeRoleSelect(c, req)
			s.JSON(c, resp, err)
		})
		g0.PUT("/roledatascope", func(c *gin.Context) {
			req := &models.ReqUpdateScope{}
			if err := c.Bind(req); err != nil {
				return
			}
			resp, err := service.Role{}.UpdateDataScope(c, req)
			s.JSON(c, resp, err)
		})
		g0.GET("/server-monitor", func(c *gin.Context) {
			resp, err := service.ServerInfo(c)
			s.JSON(c, resp, err)
		})
	}

	g1 := s.svr.Group("/api/v1/role").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.Role{}
		g1.GET("", func(c *gin.Context) {
			req := &models.ReqRoleGetPage{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetPage(c, req)
			s.JSON(c, resp, err)

		})
		g1.GET("/:id", func(c *gin.Context) {
			req := &models.ReqRoleGet{}
			if err := c.BindUri(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g1.POST("", func(c *gin.Context) {
			req := &models.ReqRoleInsert{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Insert(c, req)
			s.JSON(c, resp, err)
		})
		g1.PUT("/:id", func(c *gin.Context) {
			req := &models.ReqRoleUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Update(c, req)
			s.JSON(c, resp, err)
		})
		g1.DELETE("", func(c *gin.Context) {
			req := &models.ReqRoleDelete{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Delete(c, req)
			s.JSON(c, resp, err)
		})
	}
	g2 := s.svr.Group("/api/v1/sys-user").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.User{}
		g2.GET("", func(c *gin.Context) {
			req := &models.ReqUserGetPage{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetPage(c, req)
			s.JSON(c, resp, err)

		})
		g2.GET("/:id", func(c *gin.Context) {
			req := &models.ReqUserGet{}
			if err := c.BindUri(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g2.POST("", func(c *gin.Context) {
			req := &models.ReqUserInsert{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Insert(c, req)
			s.JSON(c, resp, err)
		})
		g2.PUT("", func(c *gin.Context) {
			req := &models.ReqUserUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Update(c, req)
			s.JSON(c, resp, err)
		})
		g2.DELETE("", func(c *gin.Context) {
			req := &models.ReqUserDelete{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Delete(c, req)
			s.JSON(c, resp, err)
		})
	}
	g3 := s.svr.Group("/api/v1/menu").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.Menu{}
		g3.GET("", func(c *gin.Context) {
			req := &models.ReqMenuGetPage{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetPage(c, req)
			s.JSON(c, resp, err)

		})
		g3.GET("/:id", func(c *gin.Context) {
			req := &models.ReqMenuGet{}
			if err := c.BindUri(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g3.POST("", func(c *gin.Context) {
			req := &models.ReqMenuInsert{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Insert(c, req)
			s.JSON(c, resp, err)
		})
		g3.PUT("/:id", func(c *gin.Context) {
			req := &models.ReqMenuUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Update(c, req)
			s.JSON(c, resp, err)
		})
		g3.DELETE("", func(c *gin.Context) {
			req := &models.ReqMenuDelete{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Delete(c, req)
			s.JSON(c, resp, err)
		})
	}
	g4 := s.svr.Group("/api/v1/sys-api").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.Api{}
		g4.GET("", func(c *gin.Context) {
			req := &models.ReqApiGetPage{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetPage(c, req)
			s.JSON(c, resp, err)

		})
		g4.GET("/:id", func(c *gin.Context) {
			req := &models.ReqApiGet{}
			if err := c.BindUri(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g4.PUT("/:id", func(c *gin.Context) {
			req := &models.ReqApiUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Update(c, req)
			s.JSON(c, resp, err)
		})
		g4.DELETE("", func(c *gin.Context) {
			req := &models.ReqApiDelete{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Delete(c, req)
			s.JSON(c, resp, err)
		})
	}
	g5 := s.svr.Group("/api/v1/dept").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.Dept{}
		g5.GET("", func(c *gin.Context) {
			req := &models.ReqDeptGetPage{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetPage(c, req)
			s.JSON(c, resp, err)

		})
		g5.GET("/:id", func(c *gin.Context) {
			req := &models.ReqDeptGet{}
			if err := c.BindUri(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g5.POST("", func(c *gin.Context) {
			req := &models.ReqDeptInsert{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Insert(c, req)
			s.JSON(c, resp, err)
		})
		g5.PUT("/:id", func(c *gin.Context) {
			req := &models.ReqDeptUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Update(c, req)
			s.JSON(c, resp, err)
		})
		g5.DELETE("", func(c *gin.Context) {
			req := &models.ReqDeptDelete{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Delete(c, req)
			s.JSON(c, resp, err)
		})
	}

	g6 := s.svr.Group("/api/v1/post").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.Post{}
		g6.GET("", func(c *gin.Context) {
			req := &models.ReqPostPage{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetPage(c, req)
			s.JSON(c, resp, err)

		})
		g6.GET("/:id", func(c *gin.Context) {
			req := &models.ReqPostGet{}
			if err := c.BindUri(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g6.POST("", func(c *gin.Context) {
			req := &models.ReqPostInsert{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Insert(c, req)
			s.JSON(c, resp, err)
		})
		g6.PUT("/:id", func(c *gin.Context) {
			req := &models.ReqPostUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Update(c, req)
			s.JSON(c, resp, err)
		})
		g6.DELETE("", func(c *gin.Context) {
			req := &models.ReqPostDelete{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Delete(c, req)
			s.JSON(c, resp, err)
		})
	}
	g7 := s.svr.Group("/api/v1/user").Use(jwtauth.Auth()).Use(permit.AuthCheckRole())
	{
		svr := service.User{}
		g7.GET("/profile", func(c *gin.Context) {
			req := &models.SysUserById{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.GetProfile(c, req)
			s.JSON(c, resp, err)

		})
		g7.POST("/avatar", func(c *gin.Context) {
			req := &models.ReqUserGet{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Get(c, req)
			s.JSON(c, resp, err)
		})
		g7.PUT("/pwd/set", func(c *gin.Context) {
			req := &models.ReqUserInsert{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.Insert(c, req)
			s.JSON(c, resp, err)
		})
		g7.PUT("/pwd/reset", func(c *gin.Context) {
			req := &models.ReqResetSysUserPwd{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.ResetPwd(c, req)
			s.JSON(c, resp, err)
		})
		g7.PUT("/status", func(c *gin.Context) {
			req := &models.ReqUserUpdate{}
			if err := c.Bind(&req); err != nil {
				return
			}
			resp, err := svr.UpdateStatus(c, req)
			s.JSON(c, resp, err)
		})
	}
}

func (s *server) Start(addr string) {
	if err := s.svr.Run(addr); err != nil {
		panic(err)
	}
}

func (s *server) JSON(c *gin.Context, rsp interface{}, err error) {
	de := ecode.Response{
		Code: 0,
		Msg:  "ok",
		Data: nil,
	}
	if err == nil {
		de.Data = rsp
		c.JSON(http.StatusOK, de)
		return
	}

	if e, ok := err.(*ecode.Response); ok {
		c.JSON(http.StatusOK, e)
	} else {
		de.Code = -1
		de.Msg = err.Error()
		c.JSON(http.StatusOK, de)
	}
}
